package com.hoshiicloud.saleorder.controller;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hoshiicloud.common.constant.DeleteStatusEnum;
import com.hoshiicloud.common.exception.ServiceException;
import com.hoshiicloud.common.rpc.Response;
import com.hoshiicloud.common.utils.ip.IpUtils;
import com.hoshiicloud.goods.entity.spu.ExtSpu;
import com.hoshiicloud.saleorder.dto.DispatchBillAndDetailDTO;
import com.hoshiicloud.saleorder.dto.OrderCalcDTO;
import com.hoshiicloud.saleorder.dto.OrderDTO;
import com.hoshiicloud.saleorder.dto.OrderMultiConditionDTO;
import com.hoshiicloud.saleorder.dto.PayResultDTO;
import com.hoshiicloud.saleorder.dto.PoBillDTO;
import com.hoshiicloud.saleorder.entity.OrderInfo;
import com.hoshiicloud.saleorder.entity.OrderMain;
import com.hoshiicloud.saleorder.feign.GoodsService;
import com.hoshiicloud.saleorder.feign.PlatStoreService;
import com.hoshiicloud.saleorder.param.BranchOrderQueryParam;
import com.hoshiicloud.saleorder.param.OrderCalcParam;
import com.hoshiicloud.saleorder.param.OrderMainIdsUpdateParam;
import com.hoshiicloud.saleorder.param.OrderMainQueryParam;
import com.hoshiicloud.saleorder.param.OrderMainStatusUpdateParam;
import com.hoshiicloud.saleorder.param.OrderQueryParam;
import com.hoshiicloud.saleorder.param.OrderSubmitParam;
import com.hoshiicloud.saleorder.param.PayOrderParam;
import com.hoshiicloud.saleorder.param.RefundOrderPayParam;
import com.hoshiicloud.saleorder.param.StoreOrderQueryParam;
import com.hoshiicloud.saleorder.service.OrderInfoService;
import com.hoshiicloud.saleorder.service.OrderMainService;
import com.hoshiicloud.saleorder.service.SaleOrderService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

/**
 * <p>
 * 销售订单业务 控制器
 * </p>
 *
 * @author zhangshuhu
 * @since 2019-05-18
 */
@Slf4j
@Validated
@RestController
@RequestMapping("/saleorder/biz")
@Api(value = "销售订单", tags = {"销售订单"})
public class SaleOrderController {

    @Autowired
    private SaleOrderService saleOrderService;

    private static final String ORDER_INFO_EXCEL_HASH_KEY = "orderInfoHashKey";

    @Autowired
    private GoodsService goodsService;

    @Autowired
    private OrderMainService orderMainService;

    @Autowired
    private OrderInfoService orderInfoService;

    @Autowired
    private PlatStoreService platStoreService;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * @param param param
     * @return com.hoshiicloud.common.rpc.Response
     * @description: 计算订单金额
     */
    @PostMapping("/calcOrderAmt")
    @ApiOperation(value = "计算订单金额")
    public Response<OrderCalcDTO> calcOrderAmt(@RequestBody @Valid OrderCalcParam param) {
        try {
            OrderCalcDTO data = saleOrderService.calcOrder(param);
            return Response.success("计算订单金额", data);
        } catch (ServiceException e) {
            log.error("计算订单金额出现异常", e);
            return Response.failed("计算订单金额出现异常：" + e.getError().getMsg());
        } catch (Exception e) {
            log.error("计算订单金额出现异常", e);
            return Response.failed("计算订单金额出现异常：" + e.getMessage());
        }
    }

    /**
     * @return com.hoshiicloud.common.rpc.Response
     * @description: 推送消息
     */
    @PostMapping("/sendMsg")
    @ApiOperation(value = "推送消息")
    public Response sendMsg(@RequestBody PoBillDTO poBillDTO) {
        try {
            saleOrderService.sendMsg(poBillDTO);
            return Response.success("推送消息成功");
        } catch (ServiceException e) {
            log.error("推送消息异常", e);
            return Response.failed("推送消息异常：" + e.getError().getMsg());
        } catch (Exception e) {
            log.error("推送消息异常", e);
            return Response.failed("推送消息异常：" + e.getMessage());
        }
    }

    /**
     * @param param
     * @return com.hoshiicloud.common.rpc.Response
     * @description: 提交订单
     */
    @PostMapping("/submitOrder")
    @ApiOperation(value = "提交订单")
    public Response submitOrder(@RequestBody @Valid OrderSubmitParam param) {
        try {
            return saleOrderService.submitOrder(param);
        } catch (ServiceException se) {
            log.error("提交订单异常", se);
            return Response.failed(se.getError().getMsg());
        } catch (Exception e) {
            log.error("提交订单异常", e);
            return Response.failed("提交订单异常：" + e.getMessage());
        }
    }

    /**
     * 根据主订单支付订单
     *
     * @param param
     * @return com.hoshiicloud.common.rpc.Response
     * @description: 订单支付
     */
    @PostMapping("/payOrder")
    @ApiOperation(value = "订单支付")
    public Response<PayResultDTO> payOrder(@RequestBody PayOrderParam param) {
        try {
            PayResultDTO data = saleOrderService.payOrder(param);
            return Response.success("订单支付成功", data);
        } catch (ServiceException se) {
            log.error("订单支付异常", se);
            return Response.failed("订单支付异常：" + se.getError().getMsg());
        } catch (Exception e) {
            log.error("订单支付异常", e);
            return Response.failed("订单支付异常：" + e.getMessage());
        }
    }

    @PostMapping("/cancelOrder")
    @ApiOperation(value = "取消订单")
    public Response cancelOrder(@RequestBody @Valid Long orderId) {
        try {
            boolean b = saleOrderService.cancelOrder(orderId);
            return Response.success(b ? "取消订单成功" : "取消订单失败");
        } catch (ServiceException se) {
            log.error("取消订单异常", se);
            return Response.failed("取消订单异常：" + se.getError().getMsg());
        } catch (Exception e) {
            log.error("取消订单异常", e);
            return Response.failed("取消订单异常：" + e.getMessage());
        }
    }

    @PostMapping("/batchCancelOrder")
    @ApiOperation(value = "批量取消订单")
    public Response batchCancelOrder(@RequestBody @Valid List<Long> orderIds) {
        try {
            boolean b = saleOrderService.batchCancelOrders(orderIds);
            return Response.success(b ? "取消订单成功" : "取消订单失败");
        } catch (ServiceException se) {
            log.error("批量取消订单异常", se);
            return Response.failed("批量取消订单异常：" + se.getError().getMsg());
        } catch (Exception e) {
            log.error("批量取消订单异常", e);
            return Response.failed("批量取消订单异常：" + e.getMessage());
        }
    }

    /**
     * 订单退款
     *
     * @param param
     * @return
     */
    @PostMapping("/refundOrder")
    @ApiOperation(value = "退款订单")
    public Response refundOrder(@RequestBody @Valid RefundOrderPayParam param) {
        try {
            saleOrderService.refundOrder(param);
            return Response.success("退款订单成功");
        } catch (ServiceException se) {
            log.error("退款订单异常", se);
            return Response.failed("退款订单异常：" + se.getError().getMsg());
        } catch (Exception e) {
            log.error("退款订单异常", e);
            return Response.failed("退款订单异常：" + e.getMessage());
        }
    }

    @PostMapping("/deleteOrder")
    @ApiOperation(value = "删除订单")
    public Response deleteOrder(@RequestBody @Valid Long orderId) {
        try {
            saleOrderService.deleteOrder(orderId);
            return Response.success("删除订单成功");
        } catch (ServiceException se) {
            log.error("删除订单异常", se);
            return Response.failed("删除订单异常：" + se.getError().getMsg());
        } catch (Exception e) {
            log.error("删除订单异常", e);
            return Response.failed("删除订单异常：" + e.getMessage());
        }
    }


    /**
     * queryWrapper.lambda().in(OrderMain::getOrderStatus, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); //
     * queryWrapper.lambda().in(OrderMain::getShippingStatus, 0, 1, 2, 3, 4, 5); // queryWrapper.lambda().in(OrderMain::getPayStatus, 0, 1,
     * 2, 3); // queryWrapper.lambda().in(OrderMain::getServiceStatus, 0, 1, 2);
     * <p>
     * // queryWrapper.lambda().eq(OrderMain::getOrderStatus, 1); // queryWrapper.lambda().eq(OrderMain::getShippingStatus, 0); //
     * queryWrapper.lambda().eq(OrderMain::getPayStatus, 0); // queryWrapper.lambda().eq(OrderMain::getServiceStatus, 0);
     *
     * @param param
     * @return
     */
    @PostMapping("/listOrder")
    @ApiOperation(value = "订单列表")
    public Response<Page<OrderDTO>> listOrder(@RequestBody @Valid OrderQueryParam param) {
        try {
            log.info("分页查询订单列表");
            QueryWrapper<OrderMain> queryWrapper = new QueryWrapper<>();
            this.setOrderQueryWrapper(queryWrapper, param.getStatus());
            if (param.getUserId() != null) {
                queryWrapper.lambda().eq(OrderMain::getMemberId, param.getUserId());

            }
            queryWrapper.lambda().eq(OrderMain::getDeleted, DeleteStatusEnum.UN_DELETED.getCode());
            queryWrapper.lambda().orderByDesc(OrderMain::getCreatedTime);
            Page<Map<String, Object>> page = new Page<>(Long.parseLong(param.getPageNumber()),
                    Long.parseLong(param.getPageSize()));
            return saleOrderService.listOrder(page, queryWrapper);
        } catch (ServiceException e) {
            return Response.failed(e.getError().getMsg());
        } catch (Exception e) {
            log.error("分页查询订单列表异常", e);
            return Response.failed("分页查询订单列表异常");
        }
    }

    @PostMapping("/listAllOrders")
    @ApiOperation(value = "所有订单列表")
    public Response<List<OrderDTO>> listAllOrders(@RequestBody @Valid OrderQueryParam param) {
        try {
            log.info("查询所有订单列表");
            QueryWrapper<OrderMain> queryWrapper = new QueryWrapper<>();
            this.setOrderQueryWrapper(queryWrapper, param.getStatus());
            if (param.getUserId() != null) {
                queryWrapper.lambda().eq(OrderMain::getMemberId, param.getUserId());
            }
            queryWrapper.lambda().eq(OrderMain::getDeleted, DeleteStatusEnum.UN_DELETED.getCode());
            queryWrapper.lambda().orderByDesc(OrderMain::getCreatedTime);
            return saleOrderService.listAllOrders(queryWrapper);
        } catch (ServiceException e) {
            return Response.failed(e.getError().getMsg());
        } catch (Exception e) {
            log.error("查询所有订单列表异常", e);
            return Response.failed("查询所有订单列表异常");
        }
    }

    @PostMapping("/viewOrder")
    @ApiOperation(value = "订单详情")
    public Response viewOrder(@RequestBody @Valid Long orderId) {
        try {
            return saleOrderService.viewOrder(orderId);
        } catch (ServiceException se) {
            return Response.failed("查询订单详情异常");

        } catch (Exception e) {
            return Response.failed("查询订单详情异常");
        }
    }

    /**
     * 店铺核销订单
     *
     * @param orderId
     * @return
     */
    @PostMapping("/verificationOrder")
    @ApiOperation(value = "订单核销")
    public Response verificationOrder(@RequestBody @Valid Long orderId) {
        try {
            return saleOrderService.verificationOrder(orderId);
        } catch (ServiceException se) {
            return Response.failed("核销订单失败");

        } catch (Exception e) {
            return Response.failed("核销订单失败");
        }
    }

    /**
     * 店铺核销订单
     *
     * @param param
     * @return
     */
    @PostMapping("/verificationBatchOrder")
    @ApiOperation(value = "批量订单核销")
    public Response verificationBatchOrder(@RequestBody @Valid OrderMainIdsUpdateParam param) {
        try {
            return saleOrderService.verificationBatchOrder(param.getOrderIds());
        } catch (ServiceException se) {
            return Response.failed("批量核销订单失败");

        } catch (Exception e) {
            return Response.failed("批量核销订单失败");
        }
    }

    /**
     * 店铺订单列表(按创建时间排序)
     *
     * @param param
     * @return
     */
    @PostMapping("/listStoreOrder")
    @ApiOperation(value = "店铺订单按创建时间排序列表")
    public Response<Page<OrderDTO>> listStoreOrder(@RequestBody @Valid StoreOrderQueryParam param) {
        try {
            log.info("分页查询订单列表");
            QueryWrapper<OrderMain> queryWrapper = new QueryWrapper<>();
            this.setOrderQueryWrapper(queryWrapper, param.getStatus());
            queryWrapper.lambda().eq(null != param.getMemberId(), OrderMain::getMemberId, param.getMemberId())
                    .eq(null != param.getStoreId(), OrderMain::getStoreId, param.getStoreId())
                    .eq(true, OrderMain::getDeleted, DeleteStatusEnum.UN_DELETED.getCode())
                    .le(null != param.getEndTime(), OrderMain::getDeliveryTime, param.getEndTime())
                    .orderByDesc(OrderMain::getCreatedTime);
            Page<Map<String, Object>> page = new Page<>(Long.parseLong(param.getPageNumber()),
                    Long.parseLong(param.getPageSize()));
            return saleOrderService.listOrder(page, queryWrapper);
        } catch (ServiceException e) {
            return Response.failed(e.getError().getMsg());
        } catch (Exception e) {
            log.error("分页查询店铺订单按创建时间排序列表异常", e);
            return Response.failed("分页查询店铺订单按创建时间排序列表异常");
        }
    }


    /**
     * 店铺订单列表(按提货时间排序)
     *
     * @param param 查询参数
     * @return Response<Page < OrderDTO>>
     */
    @PostMapping("/listStoreOrderByDeliveryTime")
    @ApiOperation(value = "店铺订单按提货时间排序列表")
    public Response<Page<OrderDTO>> listStoreOrderByDeliveryTime(@RequestBody @Valid StoreOrderQueryParam param) {
        try {
            log.info("分页查询订单列表");
            QueryWrapper<OrderMain> queryWrapper = new QueryWrapper<>();
            this.setOrderQueryWrapper(queryWrapper, param.getStatus());
            queryWrapper.lambda().eq(null != param.getMemberId(), OrderMain::getMemberId, param.getMemberId());
            queryWrapper.lambda().eq(true, OrderMain::getStoreId, param.getStoreId());
            queryWrapper.lambda().eq(StringUtils.isNotEmpty(param.getMobile()), OrderMain::getMobile, param.getMobile());
            queryWrapper.lambda().like(StringUtils.isNotEmpty(param.getOrderNo()), OrderMain::getMainNo, param.getOrderNo());
            queryWrapper.lambda().eq(true, OrderMain::getDeleted, DeleteStatusEnum.UN_DELETED.getCode());
            if (param.getStatus() == 4) { // 已完成的订单按降序排列
                queryWrapper.lambda().orderByDesc(OrderMain::getDeliveryTime);
            } else {
                queryWrapper.lambda().orderByAsc(OrderMain::getDeliveryTime);
            }
            Page<Map<String, Object>> page = new Page<>(Long.parseLong(param.getPageNumber()),
                    Long.parseLong(param.getPageSize()));
            return saleOrderService.listOrder(page, queryWrapper);
        } catch (ServiceException e) {
            return Response.failed(e.getError().getMsg());
        } catch (Exception e) {
            log.error("分页查询店铺订单按提货时间排序列表异常", e);
            return Response.failed("分页查询店铺订单按提货时间排序列表异常");
        }
    }

    /**
     * 店铺可提货订单列表
     *
     * @param param 查询参数
     * @return Response<List < OrderMain>>
     */
    @PostMapping("/listCanPickUpStoreOrder")
    @ApiOperation(value = "店铺可提货订单列表")
    public Response<List<OrderMain>> listCanPickUpStoreOrder(@RequestBody @Valid StoreOrderQueryParam param) {
        try {
            log.info("店铺可提货订单列表");
            QueryWrapper<OrderMain> queryWrapper = new QueryWrapper<>();
            this.setOrderQueryWrapper(queryWrapper, param.getStatus());
            queryWrapper.lambda().eq(null != param.getMemberId(), OrderMain::getMemberId, param.getMemberId());
            queryWrapper.lambda().eq(true, OrderMain::getStoreId, param.getStoreId());
            queryWrapper.lambda().eq(true, OrderMain::getDeleted, DeleteStatusEnum.UN_DELETED.getCode());
            queryWrapper.lambda().le(null != param.getPickUpTime(), OrderMain::getDeliveryTime, param.getPickUpTime());
            queryWrapper.lambda().orderByAsc(OrderMain::getDeliveryTime);
            return Response.data(orderMainService.list(queryWrapper));
        } catch (ServiceException e) {
            return Response.failed(e.getError().getMsg());
        } catch (Exception e) {
            log.error("查询店铺可提货订单列表异常", e);
            return Response.failed("查询店铺可提货订单列表异常");
        }
    }

    /**
     * 根据时间段查询已经付款待自提的订单
     *
     * @param param 查询参数
     * @return Response<List < OrderMain>>
     */
    @PostMapping("/listCanPickUpOrderWithTime")
    @ApiOperation(value = "根据时间段查询已经付款待自提的订单")
    public Response<List<OrderMain>> listCanPickUpOrderWithTime(@RequestBody @Valid StoreOrderQueryParam param) {
        try {
            log.info("根据时间段查询已经付款待自提的订单");
            QueryWrapper<OrderMain> queryWrapper = new QueryWrapper<>();
            this.setOrderQueryWrapper(queryWrapper, param.getStatus());
            queryWrapper.lambda()
                    .between(null != param.getBeginTime() && null != param.getEndTime(), OrderMain::getPaidTime,
                            param.getBeginTime(), param.getEndTime());
            queryWrapper.lambda().eq(true, OrderMain::getDeleted, DeleteStatusEnum.UN_DELETED.getCode());
            queryWrapper.lambda().orderByAsc(OrderMain::getDeliveryTime);
            return Response.data(orderMainService.list(queryWrapper));
        } catch (ServiceException e) {
            return Response.failed(e.getError().getMsg());
        } catch (Exception e) {
            log.error("根据时间段查询已经付款待自提的订单异常", e);
            return Response.failed("根据时间段查询已经付款待自提的订单异常");
        }
    }

    /**
     * 更新订单状态
     *
     * @param param
     * @return
     */
    @PostMapping("/verificationOrder/update")
    @ApiOperation(value = "更新订单状态")
    public Response updateOrderStatus(@RequestBody @Valid OrderMainStatusUpdateParam param) {
        try {
            return saleOrderService.updateOrderStatus(param);
        } catch (ServiceException se) {
            return Response.failed("核销订单失败");

        } catch (Exception e) {
            return Response.failed("核销订单失败");
        }
    }

    /**
     * 查询商品购买记录
     *
     * @param param 查询参数
     * @return Response<Map < String, Object>>
     */
    @PostMapping("/queryOrdersWithUserInfo")
    @ApiOperation(value = "查询商品购买记录", consumes = MediaType.APPLICATION_JSON_VALUE)
    public Response<Page<Map<String, Object>>> queryOrdersWithUserInfo(@RequestBody OrderQueryParam param) {
        try {
            log.info("查询商品购买记录");
            if (null != param.getSpuId()) {
                QueryWrapper<OrderInfo> queryWrapper = new QueryWrapper<>();
                // 因为商品购买记录需要所有店共享，所以查找同类的扩展spu
                Response<List<ExtSpu>> list = goodsService.getSimilarExtSpuById(param.getSpuId());
                if (null != list && list.getCode() == 200 && null != list.getData()) {
                    queryWrapper.in(true, "t2.spu_id",
                            list.getData().stream().map(ExtSpu::getId).collect(Collectors.toList()));
                } else {
                    queryWrapper.eq(true, "t2.spu_id", param.getSpuId());
                }
                // 默认查询已经完成的订单
                queryWrapper.in("t2.order_status", 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
                //queryWrapper.in("t2.shipping_status", 0, 1, 2, 3, 4, 5);
                queryWrapper.in("t2.pay_status", 1, 2, 3);
                queryWrapper.orderByDesc("created_time");
                Page<Map<String, Object>> page = new Page<>(Long.parseLong(param.getPageNumber()),
                        Long.parseLong(param.getPageSize()));
                return saleOrderService.queryOrdersWithUserInfo(page, queryWrapper);
            } else {
                return Response.failed("非法请求，参数不合法");
            }
        } catch (ServiceException e) {
            return Response.failed(e.getError().getMsg());
        } catch (Exception e) {
            log.error("查询商品购买记录异常", e);
            return Response.failed("查询商品购买记录异常");
        }
    }

    /**
     * 根据下单时间, 买家手机号, 订单编号进行多条件查询
     * <p>下单时间:  order_main的create_time</p>
     * <p>买家手机号: order_main的mobile</p>
     * <p>订单编号: order_main的main_no</p>
     */
    @ApiOperation(value = "多条件查询订单信息")
    @PostMapping("/multiConditionQueryOrderPage")
    public Response multiConditionQueryOrderPage(@RequestBody OrderMainQueryParam param,
            HttpServletRequest httpServletRequest) {

        Page<OrderMultiConditionDTO> page = new Page<>(Long.parseLong(param.getPageNumber()),
                Long.parseLong(param.getPageSize()));

        String key =
                "OrderMainQueryParam {" + param.toString() + "}, Page{pageNumber=" + param.getPageNumber()
                        + ",pageSize=" + param.getPageSize() + "}";

        return Response.data(saleOrderService
                .multiConditionQueryOrderPage(page, param, httpServletRequest, key));
    }

    /**
     * 根据订单编号查询订单的详情信息
     * <p>
     * <p> 需要去判断订单类型, 根据订单类型, 来返回相应的物流信息                               </p>
     * <p>     订单类型有5种                                                            </p>
     * <p>        实物订单:                                                            </p>
     * <p>        服务订单:                                                            </p>
     * <p>        实物服务订单:                                                         </p>
     * <p>        自提订单:                                                            </p>
     * <p>        外卖订单:                                                            </p>
     * <p>     1. 进度条:                                                              </p>
     * <p>          ---                                                               </p>
     * <p>               提交订单时间:                                                  </p>
     * <p>               支付订单时间:                                                  </p>
     * <p>               商家配送时间:                                                  </p>
     * <p>               交易完成时间:                                                  </p>
     * <p>     2. 订单信息: 买家信息 配送地址 发票抬头 买家留言 订单编号                       </p>
     * <p>          ---                                                               </p>
     * <p>               配送距离:                                                      </p>
     * <p>               骑手姓名:                                                      </p>
     * <p>               骑手电话:                                                      </p>
     * <p>               企业税号:                                                      </p>
     * <p>               发票类型:                                                      </p>
     * <p>               发票内容:                                                      </p>
     * <p>          ---                                                               </p>
     * <p>               支付方式:                                                      </p>
     * <p>               下单时间:                                                      </p>
     * <p>               付款时间:                                                      </p>
     * <p>               配送时间:                                                      </p>
     * <p>               完成时间:                                                      </p>
     * <p>               归档时间:                                                      </p>
     * <p>     3. 支付:交易状态 下单时间, 付款时间, 配送时间, 完成时间, 归档时间                 </p>
     * <p>     4. 订单赠品: 赠品, 规格, 市场价, 成本价 数量, 状态                             </p>
     * </p>
     *
     * @param orderMainNo 订单编号
     */
    @ApiOperation(value = "根据主单编号查询订单详情")
    @GetMapping("/orderDetailsQuery")
    public Response orderDetailsQuery(@RequestParam String orderMainNo, @RequestParam String shippingId) {
        if (StrUtil.isBlank(orderMainNo)) {
            throw new ServiceException("请传入订单Id");
        }
        if (StrUtil.isBlank(shippingId)) {
            throw new ServiceException("请传入订单类型");
        }
        return Response.data(saleOrderService.orderDetailsQuery(orderMainNo, shippingId));
    }


    /**
     * 多条件分页查询分店订单
     *
     * @param branchOrderQueryParam branchOrderQueryParam
     */
    @PostMapping("/multiConditionBranchOrders")
    @ApiOperation(value = "分页查询分店订单")
    public Response<Page> multiConditionBranchOrders(@RequestBody BranchOrderQueryParam branchOrderQueryParam,
            HttpServletRequest httpServletRequest) {
        Page page = new Page(Long.parseLong(branchOrderQueryParam.getPageNumber()),
                Long.parseLong(branchOrderQueryParam.getPageSize()));
        return Response
                .data(saleOrderService.multiConditionBranchOrders(branchOrderQueryParam, page, httpServletRequest));
    }

    /**
     * String key
     *
     * @return 返回流
     */
    @PostMapping("/branchOrdersExcelExport")
    public Response<ServletOutputStream> branchOrdersExcelExport(@RequestParam String key,
            HttpServletResponse response) {
        log.error("进入");
        return Response.data(saleOrderService.branchOrdersExcelExport(key, response));
    }

    /**
     * 获取导出RedisKey
     *
     * @param branchOrderQueryParam branchOrderQueryParam
     */
    @PostMapping("/getExportRedisKey")
    public Response<String> getExportRedisKey(@RequestBody BranchOrderQueryParam branchOrderQueryParam,
            HttpServletRequest httpServletRequest) {
        String ipAddress = IpUtils.getIpAddress(httpServletRequest);
        String redisKey = ORDER_INFO_EXCEL_HASH_KEY + ": " + ipAddress;
        saleOrderService.getExportRedisKey(branchOrderQueryParam, httpServletRequest, redisKey);
        return Response.data(redisKey);

    }


    /**
     * 得到分店订单的所有信息
     *
     * @param branchOrderQueryParam branchOrderQueryParam
     * @return List
     */
    @PostMapping("/getAllOrderInfoExcelMessage")
    public Response<List<Map<String, Object>>> getAllOrderInfoExcelMessage(
            @RequestBody BranchOrderQueryParam branchOrderQueryParam) {
        return Response.data(saleOrderService.getOrderInfoAllMessage(branchOrderQueryParam));
    }

    /**
     * 确定Key是否已经生成
     *
     * @param key key
     * @return Response
     */
    @GetMapping("/getRedisHasKey")
    public Response<Boolean> getRedisHasKey(@RequestParam String key) {
        log.error("{}", key);
        log.error("{}", saleOrderService.getRedisHasKey(key));
        return Response.data(saleOrderService.getRedisHasKey(key));
    }

    /**
     * 设置订单查询条件
     *
     * @param queryWrapper wrapper
     * @param status       订单状态
     */
    private void setOrderQueryWrapper(QueryWrapper<OrderMain> queryWrapper, Integer status) {
        if (status == 1) { // 全部订单
            queryWrapper.lambda().in(OrderMain::getOrderStatus, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        } else if (status == 2) {// 待付款订单
            queryWrapper.lambda().eq(OrderMain::getOrderStatus, 0);
        } else if (status == 3) {// 待自提订单
            queryWrapper.lambda().eq(OrderMain::getOrderStatus, 5);
        } else if (status == 4) {// 已完成订单
            queryWrapper.lambda().eq(OrderMain::getOrderStatus, 9);
        } else if (status == 5) {// 已取消订单
            queryWrapper.lambda().eq(OrderMain::getOrderStatus, 1);
        }
    }


    /**
     * 添加发货单
     *
     * @return Response
     */
    @PostMapping("/addDispatchBill")
    @ApiOperation(value = "添加发货单(020)")
    public Response addDispatchBill(@RequestBody @Valid DispatchBillAndDetailDTO dispatchBillAndDetailDTO,
            HttpServletRequest httpServletRequest) {
        saleOrderService.addDispatchBill(dispatchBillAndDetailDTO, httpServletRequest);
        return Response.data(true);
    }

    @GetMapping("/getUrlMapping")
    public Response<LinkedMultiValueMap<String, String>> getUrlMapping(HttpServletRequest request) {
        WebApplicationContext wc = WebApplicationContextUtils.getRequiredWebApplicationContext(request.getSession().getServletContext());
        RequestMappingHandlerMapping rmhp = wc.getBean(RequestMappingHandlerMapping.class);
        Map<RequestMappingInfo, HandlerMethod> map = rmhp.getHandlerMethods();
        LinkedMultiValueMap<String, String> urlMessageLinkMultiValueMap = new LinkedMultiValueMap<>();
        HashSet<Class<?>> classes = new HashSet<>();
        map.forEach((requestMappingInfo, handlerMethod) -> {
            // 拿到一个类中的所有url
            Class<?> beanType = handlerMethod.getBeanType();
            classes.add(beanType);
        });

        for (Class<?> beanType : classes) {
            Method[] methods = beanType.getMethods();
            String simpleName = beanType.getSimpleName();
            RequestMapping requestAnnotation = beanType.getAnnotation(RequestMapping.class);
            String headUrl = "";
            if (requestAnnotation != null) {
                String[] valueArr = requestAnnotation.value();
                headUrl = valueArr[0];
            }

            for (Method method : methods) {
                ApiOperation apiOperationAnnotation = method.getAnnotation(ApiOperation.class);
                GetMapping getAnnotation = method.getAnnotation(GetMapping.class);
                PostMapping postAnnotation = method.getAnnotation(PostMapping.class);
                PutMapping putAnnotation = method.getAnnotation(PutMapping.class);
                DeleteMapping deleteAnnotation = method.getAnnotation(DeleteMapping.class);
                RequestMapping requestMethodAnnotation = method.getAnnotation(RequestMapping.class);
                if (getAnnotation != null) {
                    this.addLinkMultiValueMap(urlMessageLinkMultiValueMap, simpleName, headUrl, apiOperationAnnotation,
                            getAnnotation.value());
                }
                if (postAnnotation != null) {
                    this.addLinkMultiValueMap(urlMessageLinkMultiValueMap, simpleName, headUrl, apiOperationAnnotation,
                            postAnnotation.value());
                }
                if (putAnnotation != null) {
                    this.addLinkMultiValueMap(urlMessageLinkMultiValueMap, simpleName, headUrl, apiOperationAnnotation,
                            putAnnotation.value());
                }
                if (deleteAnnotation != null) {
                    this.addLinkMultiValueMap(urlMessageLinkMultiValueMap, simpleName, headUrl, apiOperationAnnotation,
                            deleteAnnotation.value());
                }
                if (requestMethodAnnotation != null) {
                    this.addLinkMultiValueMap(urlMessageLinkMultiValueMap, simpleName, headUrl, apiOperationAnnotation,
                            requestMethodAnnotation.value());
                }
            }
        }
        return Response.data(urlMessageLinkMultiValueMap);
    }

    private void addLinkMultiValueMap(LinkedMultiValueMap<String, String> urlMessageLinkMultiValueMap, String simpleName, String headUrl,
            ApiOperation annotation, String[] valueArr) {
        for (String value : valueArr) {
            if (annotation != null) {
                String annotationValue = annotation.value();
                urlMessageLinkMultiValueMap.add(simpleName, headUrl + value + ":" + annotationValue);
            } else {
                urlMessageLinkMultiValueMap.add(simpleName, headUrl + value);
            }
        }
    }
}
